# -*- coding: utf-8 -*-
##############################################################################
#
#    baidu Solution(Odoo Expert)
#    Copyright (C) 2015 baidu Soluation (<http://baidu.com/>)
#
##############################################################################

import time
from datetime import datetime
from dateutil.relativedelta import relativedelta
from openerp.tools.translate import _
from openerp.exceptions import except_orm

from odoo import models, fields, api


class inventory_slack_wizard_line(models.Model):

    _name= 'inventory.slack.wizard.line'

    period_length= fields.Integer(u'分析周期 (天)', default=30)
    slack_length= fields.Integer(u'呆滞判定(天)', default=90)
    wizard_id= fields.Many2one('inventory.slack.wizard', u'分析表')
    name= fields.Many2one('product.product', u'产品')
    lot_id= fields.Many2one('stock.production.lot', u'批次号')
    product_category_id = fields.Many2one('product.category', u'产品类型')
    warehouse_id= fields.Many2one('stock.warehouse', u'仓库')
    location_id= fields.Many2one('stock.location', u'库位')
    company_id= fields.Many2one('res.company', u'公司',default=lambda self: self.env.user.company_id)
    date_from= fields.Date(u'节点时间', default=lambda *a: time.strftime('%Y-%m-%d'))
    date_now=fields.Float(u'当前可用总数')
    date_one=fields.Float(u'(0-1)周期')
    date_two=fields.Float(u'(1-2)周期')
    date_three=fields.Float(u'(2-3)周期')
    date_four=fields.Float(u'(3-4)周期')
    date_five=fields.Float(u'(4)周期以前')


class inventory_slack_wizard(models.Model):

    _name= 'inventory.slack.wizard'
    _description = 'Stock slack Report'
    _order = 'date_from desc'

    period_length= fields.Integer(u'分析周期 (天)', default=30)
    slack_length= fields.Integer(u'呆滞判定(天)', default=90)
    product_id= fields.Many2one('product.product', u'产品')
    product_category_id = fields.Many2one('product.category', u'产品类型')
    warehouse_id= fields.Many2one('stock.warehouse', u'仓库')
    location_id= fields.Many2one('stock.location', u'库位')
    company_id= fields.Many2one('res.company', u'公司',default=lambda self: self.env.user.company_id)
    date_from= fields.Date(u'节点时间', default=lambda *a: time.strftime('%Y-%m-%d'))
    line_count = fields.Integer(u'明细条目', compute='_compute_line_count')
    line_ids = fields.One2many('inventory.slack.wizard.line', 'wizard_id', u'报表明细')

    @api.depends('line_ids')
    def _compute_line_count(self):
        for order in self:
            i = 0
            for line in order.line_ids:
                i += 1
            order.line_count = i

    @api.model
    def default_get(self, fields):
        res = super(inventory_slack_wizard, self).default_get(fields)
        warehouse = None
        if 'warehouse_id' not in res and res.get('company_id'):
            warehouse = self.env['stock.warehouse'].search([('company_id', '=', res['company_id'])], limit=1)
        if warehouse:
            res['warehouse_id'] = warehouse.id
            res['location_id'] = warehouse.lot_stock_id.id
        return res


    def _print_report(self, data):
        res = {}

        period_length = data['form']['period_length']
        slack_length = data['form']['slack_length']
        if period_length <= 0:
            raise except_orm(_('User Error!'), _(u'分析周期必须大于0天.'))
        if slack_length <= 0:
            raise except_orm(_('User Error!'), _(u'呆滞判定时间必须大于0天.'))
        if not data['form']['date_from']:
            raise except_orm(_('User Error!'), _(u'必须设置一个分析节点时间.'))

        start = datetime.strptime(data['form']['date_from'], "%Y-%m-%d")
        slack_stop = start - relativedelta(days=slack_length)
        for i in range(5)[::-1]:
            stop = start - relativedelta(days=period_length)
            res[str(i)] = {
                'name': (i != 0 and (str((5 - (i + 1)) * period_length) + '-' + str((5 - i) * period_length)) or ('+' + str(4 * period_length))),
                'stop': start.strftime('%Y-%m-%d'),
                'start': (i != 0 and stop.strftime('%Y-%m-%d') or False),
            }
            start = stop - relativedelta(days=1)
        data['form'].update(res)
        return self.get_lines(data.get('form'))
        # return self.env.get('report').get_action([], 'inventory_slack_report.report_stockslacking', data=data)


    @api.multi
    def check_report(self):
        data = {}
        data['ids'] = self._context.get('active_ids', [])
        data['model'] = self._context.get('active_model', 'ir.ui.menu')
        for record in self:
            data['form']= self.read(['period_length', 'slack_length', 'product_id', 'product_category_id', 'warehouse_id', 'location_id', 'company_id', 'date_from'])[0]
            res = record._print_report(data)
            if res:
                # 创建tree视图结果
                for line in res:
                    self.env['inventory.slack.wizard.line'].create({
                        'wizard_id': record.id,
                        'period_length': data['form']['period_length'],
                        'slack_length': data['form']['slack_length'],
                        'name': line.get('product_id') and line.get('product_id').id or False,
                        'lot_id': line.get('lot_id') and line.get('lot_id') or False,
                        'product_category_id': data['form']['product_category_id'][0],
                        'warehouse_id': data['form']['warehouse_id'][0],
                        'location_id': data['form']['location_id'][0],
                        'company_id': data['form']['company_id'][0],
                        'date_from': data['form']['date_from'],
                        'date_now': line.get('onhand_qty', False),
                        'date_one': line.get('4', False),
                        'date_two': line.get('3', False),
                        'date_three': line.get('2', False),
                        'date_four': line.get('1', False),
                        'date_five': line.get('0', False),
                    })

        return self.action_view_line()

        # return self._print_report(data)

    @api.multi
    def action_view_line(self):

        action = self.env.ref('inventory_slack_report_tree.action_slack_report_line_tree')
        result = action.read()[0]
        result.pop('id', None)
        result['context'] = {}
        line_ids = sum([order.line_ids.ids for order in self], [])
        result['domain'] = "[('id','in',[" + ','.join(map(str, line_ids)) + "])]"
        return result

    @api.model
    def get_lines(self, form):
        res = []
        start = datetime.strptime(form['date_from'], "%Y-%m-%d")
        slack_stop = start - relativedelta(days=form['slack_length'])

        quant_obj = self.env.get('stock.quant')
        lot_obj = self.env.get('stock.production.lot')
        product_category_id = form['product_category_id'][0]
        product_obj = self.env.get('product.product')
        # 屏蔽呆滞分析时间后创建的物料
        products = product_obj.search([('categ_id', '=', product_category_id),('create_date', '<=', slack_stop.strftime('%Y-%m-%d'))])
        product_ids = products._ids
        if form.get('product_id', False) and form['product_id'][0] in product_ids:
            wizard_product_id = form['product_id'][0]
            product_ids = [wizard_product_id]

        # 先获得批次,然后通过批次来循环,找quant的时候按照批次来做.首先产品,然后批次.lot_ids再加入一个空的,来搜没有批次号的明细
        for product in product_obj.browse(product_ids):

            location_id = form['location_id'][0]
            date_from = form['date_from']
            ctx = self._context.copy()
            ctx.update({
                'location': location_id,
                'from_date': date_from,
                'to_date': date_from,
                # 'slack_stop': slack_stop
            })
            # 跳过库存为0的
            product_qty = product._compute_quantities_dict(False, False,False)
            qty_list = product_qty.get(product.id)
            if qty_list['qty_available']==0:
                continue

            # 虚拟生产库位，如果有调拨，就不算呆滞
            location_ids = self.env['stock.location'].search([('usage', '=', 'production')])
            # 根据批次来，先找出所有quant，然后根据quant找出有的批次，形成有效批次
            lot_ids = []
            # 因为批次号关系，先进先出，不管有没有核销物料，只要超期，就算作呆滞
            slack_domain = [('in_date', '<', slack_stop.strftime('%Y-%m-%d')),
                            ('location_id', '=', location_id),
                            ('product_id', '=', product.id)]
            # 这一块，原本是用作，如果批次号有核销，就不算呆滞。但批次号是有先进先出的。只要超期，就算呆滞--吴琼语
            # slack_domain = [('in_date', '>', slack_stop.strftime('%Y-%m-%d')),
            #                 ('location_id', '=', location_ids[0].id),
            #                 ('product_id', '=', product.id)]
            quant_search = quant_obj.search(slack_domain)
            for quant_lot in quant_search:
                if quant_lot.lot_id.id not in lot_ids:
                    lot_ids.append(quant_lot.lot_id.id)
            if lot_ids:
                for lot in lot_ids:
                    # if lot==False:
                    #     continue
                    product_dict={}
                    product_dict = {
                        'pname': product.name,
                        'product_id': product,
                        'onhand_qty': qty_list['qty_available'],
                        'lot_id': lot,
                    }
                    for data in range(0, 6):
                        total_qty = 0
                        if form.get(str(data)):
                            start_date = form.get(str(data)).get('start')
                            stop_date = form.get(str(data)).get('stop')
                            if not start_date:
                                domain = [('in_date', '<=', stop_date), ('location_id', '=', location_id),
                                          ('product_id', '=', product.id),('lot_id', '=', lot)]
                            else:
                                domain = [('in_date', '<=', stop_date), ('in_date', '>=', start_date),
                                          ('location_id', '=', location_id), ('product_id', '=', product.id),('lot_id', '=', lot)]
                            for quant in quant_obj.search(domain):
                                total_qty += quant.qty
                            product_dict[str(data)] = total_qty
                    res.append(product_dict)
            # 有批次号的先处理，接下来是没有批次号的
            # 虚拟生产库位，如果有调拨，就不算呆滞
            # slack_domain = [('in_date', '>', slack_stop.strftime('%Y-%m-%d')),
            #                 ('location_id', '=', location_ids[0].id),
            #                 ('product_id', '=', product.id),
            #                 ('lot_id', '=', False)]
            # if quant_obj.search(slack_domain):
            #     continue
            # product_dict={}
            # product_dict = {
            #     'pname': product.name,
            #     'product_id': product,
            #     'onhand_qty': qty_list['qty_available'],
            #     'lot_id': False,
            # }
            # # slack_stop = form['slack_stop']
            # # warehouse = form['warehouse_id'][0]
            #
            # for data in range(0, 6):
            #     total_qty = 0
            #     if form.get(str(data)):
            #         start_date = form.get(str(data)).get('start')
            #         stop_date = form.get(str(data)).get('stop')
            #         if not start_date:
            #             domain = [('in_date', '<=', stop_date), ('location_id', '=', location_id),
            #                       ('product_id', '=', product.id), ('lot_id', '=', False)]
            #         else:
            #             domain = [('in_date', '<=', stop_date), ('in_date', '>=', start_date),
            #                       ('location_id', '=', location_id), ('product_id', '=', product.id),
            #                       ('lot_id', '=', False)]
            #
            #         for quant in quant_obj.search(domain):
            #             total_qty += quant.qty
            #         product_dict[str(data)] = total_qty
            # res.append(product_dict)


        return res

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
